#include <sstream>
#include "vl_root_prop.h"
#include "vl_array_prop.h"
#include "vl_map_prop.h"
#include "vl_node_prop.h"

using namespace VL;


/**
 * +======================================================================================================================+
 * @Author: CimZzz
 * @Date: 2022-06-22 11:32:00
 * 
 * 代码分割块，以下内容涉及: 
 * 
 * 辅助结构体
 * 
 */

/**
 * @Author: CimZzz
 * @Date: 2022-06-22 11:32:23
 * 
 * VLP 层级辅助结构体
 */
struct _VLPLayer {
	// 属性指针
	VLProp* prop = nullptr;
	// 属性名
	std::string name;
	// 层级
	uint32_t layerCount = 0;
	// 原始层级
	uint32_t orgLayerCount = 0;
	// 是否为链接属性
	bool isLinkProp = false;
	// 父指针
	std::shared_ptr<_VLPLayer> parent;
	// 已存在可链接属性
	std::unordered_map<std::string, std::shared_ptr<VLProp>> existConnectPropMap;
	// 待合并的属性
	std::vector<std::shared_ptr<VLProp>> pendingCombineList;
};

/**
 * @Author: CimZzz
 * @Date: 2022-10-17 11:12:28
 * 
 * VLP if 辅助块
 */
struct _VLPIfBlock {
	// if 所在层级
	uint32_t layerCount = 0;
	// if 模式
	// 0 表示 if
	// 1 表示 elseif
	// 2 表示 else
	// 3 表示 broken
	int mode = 0;
	// 当前的分支条件是否满足
	bool effect = false;
};

/**
 * @Author: CimZzz
 * @Date: 2022-08-20 23:12:42
 * 
 * 使 VLPLayer 层级合法
 * 
 * @param layerPtr 层级指针
 * @param isArrayProp 是否为 Array 容器
 */
void _makeLayerValid(std::shared_ptr<_VLPLayer>& layerPtr, bool isArrayProp) {
	if(layerPtr->prop != nullptr) {
		return;
	}

	if(isArrayProp) {
		layerPtr->prop = new ArrayProp();
	} else {
		layerPtr->prop = new MapProp();
	}

	if(layerPtr->isLinkProp) {
		// 保存到父级链接表中
		layerPtr->parent->existConnectPropMap.emplace(layerPtr->name, std::shared_ptr<VLProp>(layerPtr->prop));
	} else {
		_makeLayerValid(layerPtr->parent, false);
		((MapProp *) layerPtr->parent->prop)->push(layerPtr->name, layerPtr->prop);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-08-24 17:40:15
 * 
 * 寻找链接节点
 * 
 * @return 链接节点指针
 */
std::shared_ptr<VLProp> _findLinkNode(std::shared_ptr<_VLPLayer>& layerPtr, const std::string& name) {
	auto iter = layerPtr->existConnectPropMap.find(name);
	if(iter != layerPtr->existConnectPropMap.end()) {
		// 找到并返回
		return iter->second;
	}

	if(layerPtr->parent.get() != nullptr) {
		return _findLinkNode(layerPtr->parent, name);
	} else {
		return std::shared_ptr<VLProp>(nullptr);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-08-24 19:12:40
 * 
 * 回退 VLP 层级
 * 
 * @return 返回父级
 */
std::shared_ptr<_VLPLayer> backToParent(std::shared_ptr<_VLPLayer>& layerPtr) {
	if(layerPtr->pendingCombineList.empty()) {
		return layerPtr->parent;
	}

	for(auto iter = layerPtr->pendingCombineList.begin() ; iter != layerPtr->pendingCombineList.end() ; iter ++) {
		if(!layerPtr->prop->combine((*iter))) {
			return std::shared_ptr<_VLPLayer>(nullptr);
		}
	}
	
	return layerPtr->parent;
}

/**
 * @Author: CimZzz
 * @Date: 2022-11-11 14:11:51
 * 
 * 解析宏值
 * 
 * @param value 原始值
 * @param feature feature 特性
 * 
 * @return 解析宏值后的字符串
 */
std::string analyzeMarcoValue(const std::string& value, VLPFeature* feature) {
	// 处理宏值
	std::string afterValue = "";
	int marcoFlagIndex = -1;
	int beginIndex = -1;
	while( (marcoFlagIndex = value.find_first_of('$', marcoFlagIndex + 1)) != -1 ) {
		// 判断存在下一个字符且下一个字符必须为 {
		if(marcoFlagIndex + 1 >= value.length()) {
			break;
		}
		if(value.at(marcoFlagIndex + 1) != '{') {
			// 起始必须为大括号
			continue;
		}
		// 寻找终止大括号
		auto endBraceIndex = value.find_first_of('}', marcoFlagIndex + 1);
		if(endBraceIndex == -1) {
			// 后面没有终止大括号了, 可以停止解析了
			break;
		}
		if(beginIndex != -1) {
			afterValue += value.substr(beginIndex, marcoFlagIndex - beginIndex);
		} else {
			afterValue = value.substr(0, marcoFlagIndex);
		}

		// 截取两个括号之间的字符串, 匹配宏值
		if(feature != nullptr && !feature->marcoMap.empty()) {
			auto marco = value.substr(marcoFlagIndex + 2, endBraceIndex - marcoFlagIndex - 2);
			auto findIter = feature->marcoMap.find(marco);
			if(findIter != feature->marcoMap.end()) {
				// 找到匹配的宏值
				afterValue += findIter->second;
			}
		}

		marcoFlagIndex = endBraceIndex;
		beginIndex = endBraceIndex + 1;
	}

	if(beginIndex == -1) {
		afterValue = value;
	} else {
		afterValue += value.substr(beginIndex);
	}

	return afterValue;
}

/**
 * +======================================================================================================================+
 * @Author: CimZzz
 * @Date: 2022-06-22 11:31:48
 * 
 * 代码分割块，以下内容涉及: 
 * 
 * 类实现方法
 * 
 */


/**
 * @Author: CimZzz
 * @Date: 2022-06-16 20:35:59
 * 
 * 构造方法
 */
RootProp::RootProp(): MapProp(VLProp::PropType::Root), errorMsg("") {

}

/**
 * @Author: CimZzz
 * @Date: 2022-06-16 15:19:23
 * 
 * 从 VLP 文件中读取
 * @param file 文件
 * @param ignoreError 是否忽略错误
 * @param feature VLP 特性集合指针
 * @return 读取成功返回 true
 */
bool RootProp::readFromVLPFile(VLFile& file, bool ignoreError, VLPFeature* feature) {
	if(!file.isExist()) {
		return false;
	}

	std::ifstream input(file.getAbsolutePath());
	if(input.bad()) {
		return false;
	}

	std::string line;
	// 用来保存层级指针的队列
	std::shared_ptr<_VLPLayer> layerPtr(new _VLPLayer);
	layerPtr->layerCount = 0;
	layerPtr->prop = this;
	
	int errorCode = 0;

	// 当前层级
	unsigned int currentLayer = 0;
	// if 块列表
	std::vector<std::shared_ptr<_VLPIfBlock>> ifBlockList;
	// 最深层的 if 块
	std::shared_ptr<_VLPIfBlock> lastIfBlock;
	// 错误信息
	std::string errorMsg;
	while(std::getline(input, line)) {
		// 读取行文本
		// 去掉行首尾空格
		line.erase(0, line.find_first_not_of(' '));
		line.erase(line.find_last_not_of(' ') + 1);
		// 空白行和注释行跳过
		if(line.length() == 0 || line.at(0) == '#') {
			continue;
		}
		// 分析行首 \t 制表符决定归属层级
		unsigned int orgLayerCount = line.find_first_not_of('\t') + 1;
		if(orgLayerCount != 1) {
			// 抹掉 \t 和左边空格
			line.erase(0, line.find_first_not_of('\t'));
			line.erase(0, line.find_first_not_of(' '));
		}
		// 再次判断是否为空
		if(line.length() == 0 || line.at(0) == '#') {
			continue;
		}

		// 检查 if 块层级
		lastIfBlock = std::shared_ptr<_VLPIfBlock>(nullptr);
		while(!ifBlockList.empty()) {
			lastIfBlock = ifBlockList.back();
			if(lastIfBlock->layerCount > orgLayerCount) {
				ifBlockList.pop_back();
				continue;
			}
			break;
		}

		if(lastIfBlock.get() != nullptr) {
			// 存在 if block, 检查当前层级是否合法
			if(!lastIfBlock->effect && orgLayerCount > lastIfBlock->layerCount) {
				// 当前 if 块没有生效, 高于这个层级的配置都视为失效
				continue;
			}
		}

		// 判断是否为待链接属性
		bool isLinkProp = line.at(0) == '@';
		if(isLinkProp) {
			// 移除头部 @ 符号以及空格
			line.erase(0, 1);
			line.erase(0, line.find_first_not_of(' '));

			// 判断是不是关键词 if
			auto firstSpaceIndex = line.find_first_of(' ');
			// 如果存在空格, 判断前缀是不是 if、else、elseif
			if(firstSpaceIndex == 2 || line.length() == 2) {
				// 空格前有两个字符, 判断是不是 if
				if(line.at(0) == 'i' && line.at(1) == 'f') {
					bool isEffect = false;
					if(line.length() > 2 && line.at(2) == ' ') {
						// 先抹掉 if 和空格
						line.erase(0, 2);
						line.erase(0, line.find_first_not_of(' '));
						if(!line.empty()) {
							// 判断首字符是否为 !
							bool isAnti = false;
							if(line.at(0) == '!') {
								// 如果是 ! 开头的特性, 表示相反
								isAnti = true;
								// 抹去感叹号和空格
								line.erase(0, 1);
								line.erase(0, line.find_first_not_of(' '));
							}
							if(!line.empty()) {
								if(feature != nullptr) {
									// 在特性中找有无该特性
									isEffect = feature->nameSet.find(line) != feature->nameSet.end();
									if(isAnti) {
										isEffect = !isEffect;
									}
								} else {
									isEffect = isAnti;
								}
							}
						}
					}

					// 检查过往 if
					if(lastIfBlock.get() != nullptr) {
						if(lastIfBlock->layerCount == orgLayerCount) {
							lastIfBlock->effect = isEffect;
							lastIfBlock->mode = 0;
							continue;
						}
					}

					std::shared_ptr<_VLPIfBlock> ifBlock(new _VLPIfBlock);
					ifBlock->layerCount = orgLayerCount;
					ifBlock->effect = isEffect;
					ifBlock->mode = 0;
					ifBlockList.push_back(ifBlock);
					continue;
				}
			} else if(firstSpaceIndex == 4 || line.length() == 4) {
				// 空格前有四个字符, 判断是不是 else
				if(line.at(0) == 'e' && line.at(1) == 'l' && line.at(2) == 's' && line.at(3) == 'e') {
					// 确定是 else
					if(lastIfBlock.get() == nullptr) {
						// 之前没有 if 或者 elseif
						std::shared_ptr<_VLPIfBlock> ifBlock(new _VLPIfBlock);
						ifBlock->layerCount = orgLayerCount;
						ifBlock->effect = false;
						ifBlock->mode = 4;
						ifBlockList.push_back(ifBlock);
						continue;
					}
					// 之前的条件块层级不匹配
					if(lastIfBlock->layerCount != orgLayerCount) {
						std::shared_ptr<_VLPIfBlock> ifBlock(new _VLPIfBlock);
						ifBlock->layerCount = orgLayerCount;
						ifBlock->effect = false;
						ifBlock->mode = 4;
						ifBlockList.push_back(ifBlock);
						continue;
					}

					// 之前的条件块不是 if 或者 elseif 或者之前的条件块已经生效
					if((lastIfBlock->mode != 0 && lastIfBlock->mode != 1) || lastIfBlock->effect) {
						lastIfBlock->effect = false;
						lastIfBlock->mode = 4;
						continue;
					}

					lastIfBlock->effect = true;
					lastIfBlock->mode = 2;
					continue;
				}
			} else if(firstSpaceIndex == 6 || line.length() == 6) {
				// 空格前有六个字符, 判断是不是 elseif
				if(line.at(0) == 'e' && line.at(1) == 'l' && line.at(2) == 's' && line.at(3) == 'e' && line.at(4) == 'i' && line.at(5) == 'f') {
					// 确定是 elseif
					// 抹去 elseif 和首部空格
					if(lastIfBlock.get() == nullptr) {
						// 之前没有 if 或者 elseif
						std::shared_ptr<_VLPIfBlock> ifBlock(new _VLPIfBlock);
						ifBlock->layerCount = orgLayerCount;
						ifBlock->effect = false;
						ifBlock->mode = 4;
						ifBlockList.push_back(ifBlock);
						continue;
					}

					// 之前的条件块层级不匹配
					if(lastIfBlock->layerCount != orgLayerCount) {
						std::shared_ptr<_VLPIfBlock> ifBlock(new _VLPIfBlock);
						ifBlock->layerCount = orgLayerCount;
						ifBlock->effect = false;
						ifBlock->mode = 4;
						ifBlockList.push_back(ifBlock);
						continue;
					}

					// 之前的条件块不是 if 或者 elseif 或者之前的条件块已经生效
					if((lastIfBlock->mode != 0 && lastIfBlock->mode != 1) || lastIfBlock->effect) {
						lastIfBlock->effect = false;
						lastIfBlock->mode = 4;
						continue;
					}
					
					bool isEffect = false;
					if(line.length() > 6 && line.at(6) == ' ') {
						// 先抹掉 if 和空格
						line.erase(0, 6);
						line.erase(0, line.find_first_not_of(' '));
						if(!line.empty()) {
							// 判断首字符是否为 !
							bool isAnti = false;
							if(line.at(0) == '!') {
								// 如果是 ! 开头的特性, 表示相反
								isAnti = true;
								// 抹去感叹号和空格
								line.erase(0, 1);
								line.erase(0, line.find_first_not_of(' '));
							}
							if(!line.empty()) {
								if(feature != nullptr) {
									// 在特性中找有无该特性
									isEffect = feature->nameSet.find(line) != feature->nameSet.end();
									if(isAnti) {
										isEffect = !isEffect;
									}
								} else {
									isEffect = isAnti;
								}
							}
						}
					}
					
					lastIfBlock->effect = isEffect;
					lastIfBlock->mode = 1;
					continue;
				}
			} else if(firstSpaceIndex == 5 || line.length() == 5) {
				if(line.at(0) == 'e' && line.at(1) == 'r' && line.at(2) == 'r' && line.at(3) == 'o' && line.at(4) == 'r') {
					if(ignoreError) {
						continue;
					}
					// 判断是 error
					// 抹掉 error 和空格
					line.erase(0, 5);
					line.erase(0, line.find_first_not_of(' '));
					errorCode = 8;
					errorMsg = line;
					break;
				}
			}
		}

		unsigned int layerCount = orgLayerCount;
		// 如果存在 if block, 根据 if block 嵌套层级计算出真正的层级
		if(lastIfBlock.get() != nullptr) {
			if(lastIfBlock->layerCount == orgLayerCount) {
				ifBlockList.pop_back();
				if(!ifBlockList.empty()) {
					lastIfBlock = ifBlockList.back();
				} else {
					lastIfBlock = std::shared_ptr<_VLPIfBlock>(nullptr);
				}
			}
			layerCount = orgLayerCount - ifBlockList.size();
 		}

		
		// 层级检查
		if(layerCount > layerPtr->layerCount + 1) {
			// 层级异常
			errorCode = 1;
			break;
		}

		while(layerCount <= layerPtr->layerCount) {
			// 层级回退, 移除无效层级
			layerPtr = backToParent(layerPtr);
			if(layerPtr.get() == nullptr) {
				errorCode = 2;
				break;
			}
		}
		// 解析节点属性
		bool isArrayItem = line.at(0) == '-';
		bool isContainer = line.at(line.length() - 1) == ':';
		if(isArrayItem && isContainer) {
			// 两者不可并存
			errorCode = 3;
			break;
		}
		if(isContainer) {
			std::string name = line.substr(0, line.length() - 1);
			// 去掉属性名首尾空格
			name.erase(0, name.find_first_not_of(' '));
			name.erase(name.find_last_not_of(' ') + 1);

			auto newLayerPtr = std::shared_ptr<_VLPLayer>(new _VLPLayer);
			newLayerPtr->name = name;
			newLayerPtr->isLinkProp = isLinkProp;
			newLayerPtr->layerCount = layerCount;
			newLayerPtr->orgLayerCount = orgLayerCount;
			newLayerPtr->parent = layerPtr;
			layerPtr = newLayerPtr;
			continue;
		}
		if(isArrayItem) {
			// 抹掉 - 和左边空格
			line.erase(0, line.find_first_not_of('-'));
			line.erase(0, line.find_first_not_of(' '));

			_makeLayerValid(layerPtr, true);

			if(!layerPtr->prop->isArray()) {
				// 类型不正确
				errorCode = 4;
				break;
			}

			((ArrayProp *)layerPtr->prop)->add(analyzeMarcoValue(line, feature));
			continue;
		} else {
			// 寻找冒号, 不存在冒号表示异常属性
			int colonIdx = line.find(':');
			if(colonIdx == -1) {
				// 不存在冒号, 检查是否为 Link 节点
				if(line.at(0) == '{' && line.at(line.length() - 1) == '}') {
					// 是 Link 节点, 逐级向上寻找 Link 节点
					line.erase(0, 1);
					line.erase(line.length() - 1);
					auto linkProp = _findLinkNode(layerPtr, line);

					if(linkProp.get() == nullptr) {
						// 没有找到链接, 跳过
						continue;
					}

					// 找到 Prop, 进行合并
					if(linkProp->isArray()) {
						_makeLayerValid(layerPtr, true);
					} else {
						_makeLayerValid(layerPtr, false);
					}
					layerPtr->pendingCombineList.push_back(linkProp);
					continue;
				}
				// 不合法
				errorCode = 5;
				break;
			}

			std::string name = line.substr(0, colonIdx);
			// 去掉属性名首尾空格
			name.erase(0, name.find_first_not_of(' '));
			name.erase(name.find_last_not_of(' ') + 1);

			std::string value = line.substr(colonIdx + 1);
			value.erase(0, value.find_first_not_of(' '));
			value.erase(value.find_last_not_of(' ') + 1);
			
			if(isLinkProp) {
				// 如果是 Link 属性
				std::shared_ptr<VLProp> nodeProp(new NodeProp(value));
				nodeProp->setName(name);
				layerPtr->existConnectPropMap.emplace(name, nodeProp);
				continue;
			}

			_makeLayerValid(layerPtr, false);
			if(!layerPtr->prop->isMap()) {
				// 类型不正确
				errorCode = 6;
				break;
			}

			((MapProp *) layerPtr->prop)->push(name, analyzeMarcoValue(value, feature));
			continue;
		}
	}

	if(!errorCode) {
		while(layerPtr.get() != nullptr) {
			if(layerPtr->layerCount == 0) {
				break;
			}
			layerPtr = backToParent(layerPtr);

			if(layerPtr.get() == nullptr) {
				errorCode = 7;
				break;
			}

		}
	}

	if(errorCode) {
		this->clear();
		input.close();
		this->errorMsg = errorMsg;
		return false;
	}

	input.close();
	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-16 15:18:44
 * 
 * 写入 VLC 文件
 * @param file 文件
 * @return 写入成功返回 true
 */
bool RootProp::writeToVLCFile(VLFile& file) {
	if(!file.newFile()) {
		return false;
	}

	std::ofstream output;
	output.open(file.getAbsolutePath(), std::ios::out | std::ios::trunc);
	if(output.bad()) {
		return false;
	}
	// 执行写入逻辑
	// 先写入长度
	char buf[16];
	RootProp::itobytes(this->children.size(), buf);
	output.write(buf, 4);

	bool result = true;
	// 遍历 children map
	auto end = this->children.end();
	for(auto i = this->children.begin() ; i != end ; i ++) {
		if(!writeVLCProp(output, buf, i->second.get())) {
			result = false;
			break;
		}
	}

	if(output.fail() || output.bad()) {
		result = false;
	}

	output.close();

	return result;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-16 15:19:23
 * 
 * 从 VLC 文件中读取
 * @param file 文件
 * @return 读取成功返回 true
 */
bool RootProp::readFromVLCFile(VLFile& file) {
	if(!file.isExist()) {
		return false;
	}

	std::ifstream input(file.getAbsolutePath());
	if(input.bad()) {
		return false;
	}

	char buf[2049];

	// 先读取长度
	long length = RootProp::readVLCLength(input, buf);
	if(length == -1) {
		input.close();
		return false;
	}

	for(unsigned int i = 0 ; i < length ; i ++) {
		auto childProp = RootProp::readVLCProp(input, buf);
		if(childProp.get() == nullptr) {
			this->clear();
			input.close();
			return false;
		}
		(*this)(childProp->getName(), childProp);
	}

	input.close();
	return true;
}


/**
 * @Author: CimZzz
 * @Date: 2022-06-21 11:04:46
 * 
 * 构建属性打印信息
 */
std::string RootProp::buildPropPrintInfo() {
	std::stringstream stream;
	stream << "(";
	stream << "size: " << this->children.size();
	stream << ")";
	return stream.str();
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 15:16:41
 * 
 * 打印属性节点信息, 设置前缀
 * @param prefix 前缀
 */
void RootProp::printWithPrefix(std::string prefix) {
	VLProp::printWithPrefix(prefix);
	std::string childPrefix = "\t" + prefix;
	for(auto i = this->children.begin() ; i != this->children.end() ; i ++) {
		i->second->printWithPrefix(childPrefix);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-10-24 17:53:27
 * 
 * 获取错误信息
 * 
 * @return 错误信息
 */
std::string RootProp::getErrorMessage() {
	return this->errorMsg;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 18:08:22
 * 
 * 读取 VLC 属性
 * @param input 输入流
 * @param buf 缓冲区
 * @return 属性对象指针
 */
std::shared_ptr<VLProp> RootProp::readVLCProp(std::ifstream & input, char * buf) {
	std::shared_ptr<VLProp> result(nullptr);
	// 先读取 name
	auto namePtr = RootProp::readVLCStr(input, buf);
	if(namePtr.get() == nullptr) {
		return result;
	}

	// 读取属性类型
	if(!RootProp::readbytes(input, buf, 1)) {
		return result;
	}
	VLProp::PropType propType = (VLProp::PropType) buf[0];

	switch(propType) {
		case VLProp::PropType::Node : {
			// 获取节点属性
			if(!RootProp::readbytes(input, buf, 1)) {
				return result;
			}
			NodeProp::PropValueType valueType = (NodeProp::PropValueType)(buf[0] & 0xFF);
			NodeProp* prop = nullptr;
			switch(valueType) {
				case NodeProp::PropValueType::String: {
					// 节点属性
					// 获取属性值
					auto valuePtr = RootProp::readVLCStr(input, buf);
					if(valuePtr.get() == nullptr) {
						return result;
					}
					prop = new NodeProp(valuePtr);
					break;
				}
				case NodeProp::PropValueType::Boolean : {
					if(!RootProp::readbytes(input, buf, 1)) {
						return result;
					}
					bool value = (bool)buf[0];
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::Byte :{
					if(!RootProp::readbytes(input, buf, 1)) {
						return result;
					}
					int8_t value = (int8_t)buf[0];
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::UByte : {
					if(!RootProp::readbytes(input, buf, 1)) {
						return result;
					}
					uint8_t value = (uint8_t)buf[0];
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::Short : {
					if(!RootProp::readbytes(input, buf, 2)) {
						return result;
					}
					int16_t value = (int16_t)(buf[0] & 0xFF) | (((int16_t)(buf[1] & 0xFF)) << 8);
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::UShort : {
					if(!RootProp::readbytes(input, buf, 2)) {
						return result;
					}
					uint16_t value = (uint16_t)(buf[0] & 0xFF) | (((uint16_t)(buf[1] & 0xFF)) << 8);
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::Int : {
					if(!RootProp::readbytes(input, buf, 4)) {
						return result;
					}
					int32_t value = (int32_t)(buf[0] & 0xFF) | (((int32_t)(buf[1] & 0xFF)) << 8) | (((int32_t)(buf[2] & 0xFF)) << 16) | (((int32_t)(buf[3] & 0xFF)) << 24);
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::UInt : {
					if(!RootProp::readbytes(input, buf, 4)) {
						return result;
					}
					uint32_t value = (uint32_t)(buf[0] & 0xFF) | (((uint32_t)(buf[1] & 0xFF)) << 8) | (((uint32_t)(buf[2] & 0xFF)) << 16) | (((uint32_t)(buf[3] & 0xFF)) << 24);
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::Long : {
					if(!RootProp::readbytes(input, buf, 8)) {
						return result;
					}
					int64_t value = (int64_t)(buf[0] & 0xFF) | 
						(((int64_t)(buf[1] & 0xFF)) << 8) | 
						(((int64_t)(buf[2] & 0xFF)) << 16) | 
						(((int64_t)(buf[3] & 0xFF)) << 24) |
						(((int64_t)(buf[4] & 0xFF)) << 32) |
						(((int64_t)(buf[5] & 0xFF)) << 40) |
						(((int64_t)(buf[6] & 0xFF)) << 48) |
						(((int64_t)(buf[7] & 0xFF)) << 56);
					prop = new NodeProp(value);
					break;
				}
				case NodeProp::PropValueType::ULong : {
					if(!RootProp::readbytes(input, buf, 8)) {
						return result;
					}
					uint64_t value = (uint64_t)(buf[0] & 0xFF) | 
						(((uint64_t)(buf[1] & 0xFF)) << 8) | 
						(((uint64_t)(buf[2] & 0xFF)) << 16) | 
						(((uint64_t)(buf[3] & 0xFF)) << 24) |
						(((uint64_t)(buf[4] & 0xFF)) << 32) |
						(((uint64_t)(buf[5] & 0xFF)) << 40) |
						(((uint64_t)(buf[6] & 0xFF)) << 48) |
						(((uint64_t)(buf[7] & 0xFF)) << 56);
					prop = new NodeProp(value);
					break;
				}
				default:
					return result;
			}

			result.reset(prop);
			prop->setName(*namePtr.get());
			break;
		}
		case VLProp::PropType::Array : {
			// 数组属性
			// 获取数组长度
			long arrayLength = RootProp::readVLCLength(input, buf);
			if(arrayLength == -1) {
				return result;
			}

			ArrayProp* prop = new ArrayProp();
			prop->setName(*namePtr.get());
			result.reset(prop);
			for(unsigned int i = 0 ; i < arrayLength ; i ++) {
				auto childProp = RootProp::readVLCProp(input, buf);
				if(childProp.get() == nullptr) {
					result.reset();
					return result;
				}
				(*prop)(childProp);
			}
			break;
		}
		case VLProp::PropType::Map : {
			// 映射表属性
			// 获取映射表长度
			long mapLength = RootProp::readVLCLength(input, buf);
			if(mapLength == -1) {
				return result;
			}

			MapProp* prop = new MapProp();
			prop->setName(*namePtr.get());
			result.reset(prop);
			for(unsigned int i = 0 ; i < mapLength ; i ++) {
				auto childProp = RootProp::readVLCProp(input, buf);
				if(childProp.get() == nullptr) {
					result.reset();
					return result;
				}
				(*prop)(childProp->getName(), childProp);
			}
		}
		default: break;
	}

	return result;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 17:37:36
 * 
 * 写入 VLC 属性
 * @param output 输出流
 * @param buf 缓冲区
 * @param prop 属性指针
 * @return 写入成功返回 true
 */
bool RootProp::writeVLCProp(std::ofstream & output, char * buf, VLProp* prop) {
	// 先写入 name 尺寸 + name 数据
	std::string name = prop->getName();
	unsigned int nameLength = name.length();
	RootProp::itobytes(nameLength, buf);
	output.write(buf, 4);
	if(nameLength != 0) {
		output.write(name.c_str(), nameLength);
	}

	// 写入节点类型
	VLProp::PropType propType = prop->getType();
	buf[0] = ((char)(propType)) & 0xFF;
	output.write(buf, 1);
	switch(propType) {
		case VLProp::PropType::Node : {
			// 节点属性, 写入属性值
			NodeProp* nodeProp = (NodeProp *) prop;
			NodeProp::PropValueType valueType = nodeProp->valueType;
			// 写入 Node 值类型
			buf[0] = ((char)valueType) & 0xFF;
			output.write(buf, 1);
			switch(valueType) {
				case NodeProp::PropValueType::Void: {
					break;
				}
				case NodeProp::PropValueType::String: {
					std::string value = nodeProp->getValue();
					unsigned int valueLength = value.length();
					RootProp::itobytes(valueLength, buf);
					output.write(buf, 4);
					if(valueLength != 0) {
						output.write(value.c_str(), valueLength);
					}
					break;
				}
				case NodeProp::PropValueType::Boolean : {
					bool value = nodeProp->getBoolean();
					buf[0] = ((char)value) & 0xFF;
					output.write(buf, 1);
					break;
				}
				case NodeProp::PropValueType::Byte : {
					int8_t value = nodeProp->getByte();
					buf[0] = ((char)value) & 0xFF;
					output.write(buf, 1);
					break;
				}
				case NodeProp::PropValueType::UByte : {
					uint8_t value = nodeProp->getUByte();
					buf[0] = ((char)value) & 0xFF;
					output.write(buf, 1);
					break;
				}
				case NodeProp::PropValueType::Short : {
					int16_t value = nodeProp->getShort();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					output.write(buf, 2);
					break;
				}
				case NodeProp::PropValueType::UShort : {
					uint16_t value = nodeProp->getUShort();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					output.write(buf, 2);
					break;
				}
				case NodeProp::PropValueType::Int : {
					int32_t value = nodeProp->getInt();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					buf[2] = (value >> 16) & 0xFF;
					buf[3] = (value >> 24) & 0xFF;
					output.write(buf, 4);
					break;
				}
				case NodeProp::PropValueType::UInt : {
					uint32_t value = nodeProp->getUInt();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					buf[2] = (value >> 16) & 0xFF;
					buf[3] = (value >> 24) & 0xFF;
					output.write(buf, 4);
					break;
				}
				case NodeProp::PropValueType::Long : {
					int64_t value = nodeProp->getLong();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					buf[2] = (value >> 16) & 0xFF;
					buf[3] = (value >> 24) & 0xFF;
					buf[4] = (value >> 32) & 0xFF;
					buf[5] = (value >> 40) & 0xFF;
					buf[6] = (value >> 48) & 0xFF;
					buf[7] = (value >> 56) & 0xFF;
					output.write(buf, 8);
					break;
				}
				case NodeProp::PropValueType::ULong : {
					uint64_t value = nodeProp->getULong();
					buf[0] = value & 0xFF;
					buf[1] = (value >> 8) & 0xFF;
					buf[2] = (value >> 16) & 0xFF;
					buf[3] = (value >> 24) & 0xFF;
					buf[4] = (value >> 32) & 0xFF;
					buf[5] = (value >> 40) & 0xFF;
					buf[6] = (value >> 48) & 0xFF;
					buf[7] = (value >> 56) & 0xFF;
					output.write(buf, 8);
					break;
				}
			}
			break;
		}

		case VLProp::PropType::Array : {
			// 数组属性
			// 写入数组长度
			ArrayProp* arrayProp = (ArrayProp *) prop;
			unsigned int arrayLength = arrayProp->array.size();
			RootProp::itobytes(arrayLength, buf);
			output.write(buf, 4);
			// 遍历子元素写入
			if(arrayLength > 0) {
				auto arrayEnd = arrayProp->array.end();
				for(auto i = arrayProp->array.begin() ; i != arrayEnd ; i ++) {
					if(!RootProp::writeVLCProp(output, buf, i->get())) {
						return false;
					}
				}
			}
			break;
		}

		case VLProp::PropType::Map : {
			// 映射表属性
			// 写入映射表长度
			MapProp* mapProp = (MapProp *) prop;
			unsigned int mapLength = mapProp->children.size();
			RootProp::itobytes(mapLength, buf);
			output.write(buf, 4);
			// 遍历子元素写入
			if(mapLength > 0) {
				auto mapEnd = mapProp->children.end();
				for(auto i = mapProp->children.begin() ; i != mapEnd ; i ++) {
					if(!RootProp::writeVLCProp(output, buf, i->second.get())) {
						return false;
					}
				}
			}
			break;
		}

		default: return false;
	}

	return true;
}



/**
 * @Author: CimZzz
 * @Date: 2022-06-21 18:28:00
 * 
 * 获取 VLC 模式下字符串
 * @param input 输入流
 * @param buf 缓冲区
 * @return 字符串指针
 */
std::shared_ptr<std::string> RootProp::readVLCStr(std::ifstream & input, char * buf) {
	std::shared_ptr<std::string> result(nullptr);
	// 先读取长度
	unsigned int length = RootProp::readVLCLength(input, buf);
	if(length > 0 && !RootProp::readbytes(input, buf, length)) {
		return result;
	}

	buf[length] = '\0';
	result.reset(new std::string(buf));
	return result;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 18:33:37
 * 
 * 获取 VLC 模式下的长度
 * @param input 输入流
 * @param buf 缓冲区
 * @return 长度值
 */
long RootProp::readVLCLength(std::ifstream & input, char * buf) {
	if(!RootProp::readbytes(input, buf, 4)) {
		return -1;
	}

	return RootProp::bytestoi(buf);
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 18:10:20
 * 
 * 读取指定尺寸的字节
 * @param input 输入流
 * @param buf 缓冲区
 * @param size 字节尺寸
 * @return 读取成功返回 true
 */
bool RootProp::readbytes(std::ifstream & input, char * buf, unsigned int size) {
	unsigned int extracted = input.read(buf, size).gcount();
	if(extracted != size) {
		return false;
	}
	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-06-21 17:29:56
 * 
 * 将整数转换为四字节形式
 * @param number 整数
 * @param buf 字节缓冲
 */
void RootProp::itobytes(unsigned int number, char * buf) {
	buf[0] = number & 0xFF;
	buf[1] = (number >> 8) & 0xFF;
	buf[2] = (number >> 16) & 0xFF;
	buf[3] = (number >> 24) & 0xFF;
}


/**
 * @Author: CimZzz
 * @Date: 2022-06-21 17:32:06
 * 
 * 将四字节组装成整数
 * @param buf 字节缓冲
 * @return 整数
 */
unsigned int RootProp::bytestoi(char * buf) {
	return (buf[0] & 0xFF) | ((buf[1] & 0xFF) << 8) | ((buf[2] & 0xFF) << 16) | ((buf[3] & 0xFF) << 24);
}